#pragma once
#include "CDOCollection.h"

class CTransitionRoot;


typedef void (__stdcall *PFNOwnerDirtyFlag)(CDependencyObject *, DirtyFlags::Value);

class CUIElementCollection :
	public CDOCollection
{
public: 
	CUIElementCollection(CCoreServices * pCore);
	virtual ~CUIElementCollection();
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	virtual XBOOL ParticipatesInManagedTreeInternal();
	virtual HRESULT SetOwner(CDependencyObject * pOwner, PFNOwnerDirtyFlag * pfnOwnerDirtyFlag);
	virtual HRESULT OnAddToCollection(CDependencyObject * pDO);
private: 
	HRESULT OnRemoveFromCollection(CDependencyObject * pDO);
public: 
	virtual HRESULT OnRemoveFromCollection(CDependencyObject * pDO, XINT32 iPreviousIndex);
	virtual HRESULT Append(CDependencyObject * pObject, XUINT32 * pnIndex);
	virtual HRESULT Insert(XUINT32 nIndex, CDependencyObject * pObject);
private: 
	CDependencyObject * Remove(XUINT32 nIndex, CDependencyObject * pObject);
public: 
	virtual CDependencyObject * Remove(CDependencyObject * pObject);
	virtual void * RemoveAt(XUINT32 nIndex);
	virtual HRESULT Clear();
	virtual HRESULT Move(XINT32 nIndex, XINT32 nPosition);
	virtual CDependencyObject * RemoveAtImpl(XUINT32 nIndex);
	virtual HRESULT ValidateItem(CDependencyObject * pObject);
	HRESULT GetChildrenInRenderOrderInternal(CUIElement * * * pppUIElements, XUINT32 * puiChildCount);
	HRESULT RemoveAllElements(XBOOL bTryUnloadingElements);
	void SetSortedCollectionDirty(XBOOL fDirty);
	HRESULT RemoveUnloadedElement(CUIElement * pTarget, XBOOL * pfExecutedUnload);
	HRESULT GetLocalTransitionRoot(CTransitionRoot * * ppTransitionRoot, XBOOL ensureTransitionRoot);
protected: 
	virtual HRESULT LeaveImpl(CDependencyObject * pNamescopeOwner, struct LeaveParams params);
	virtual void OnRemovingDependencyObject(CDependencyObject * pDO);
public: 
	XBOOL HasUnloadingStorage();
	XBOOL IsUnloadingElement(CUIElement * pTarget);
	HRESULT RemoveAllUnloadingChildren();
	XUINT32 GetUnloadingChildrenCompositionPathCounter();
	struct UIElementCollectionUnloadingStorage * m_pUnloadingStorage;
private: 
	void OnChildrenChanged(CDependencyObject * pChildSender);
	XBOOL HasSortedChildren() const;
	XBOOL NeedsToSort(CUIElement * * ppUnsortedUIElements, XUINT32 uiChildCount) const;
	void DestroySortedCollection();
	HRESULT SortChildren();
	XBOOL UnloadElement(XUINT32 nIndex, CUIElement * pRemove, enum UnloadCleanup initialClearLogic);
	XUINT32 IndexIndicatingUnloadingElement();
	static HRESULT EnsureUnloadingStorage(CUIElementCollection * pCollection);
	CTransitionRoot * m_pLocalTransitionRoot;
	CUIElement * * m_ppSortedUIElements;
	XBOOL m_fSortedElementsDirty;
};

